package com.ruoyi.common.utils.file.transfer;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;

/**
 * 远程文件传输工具类 ftp
 *
 * @author ysz
 * @date 2024/6/21 9:30
 */
public class FtpTransferUtil implements FileTransferUtils{
    private static final Logger log = LoggerFactory.getLogger(FtpTransferUtil.class);
    FTPClient ftpClient;

    /**
     * 获取连接
     **/
    @Override
    public boolean getConnection(TransferConnectEntity transferConnectEntity) {
        ftpClient = new FTPClient();
        //传输命令的超时
//        ftpClient.setDefaultTimeout(20000);
//        //两个服务连接超时时间
//        ftpClient.setConnectTimeout(10000);
//        //被动模式下设置数据传输的超时时间
//        ftpClient.setDataTimeout(15000);
        try {
            ftpClient.connect(transferConnectEntity.getIp(), transferConnectEntity.getPort());
            //账户密码登录
            boolean loginFlag = ftpClient.login(transferConnectEntity.getUsername(), transferConnectEntity.getPassword());
            if (!loginFlag) {
                return false;
            }
        } catch (IOException e) {
            return false;
        }
        return true;
    }

    /**
     * 获取远程文件
     */
    @Override
    public boolean getFile(TransferConnectEntity transferConnectEntity, String remotePath, String remoteFile, String localPath) {
        getConnection(transferConnectEntity);
        OutputStream out = null;
        try {
            // 工作目录切换到下载文件的目录下
            if (!ftpClient.changeWorkingDirectory(remotePath)) {
                log.info("目录不存在：{}", remotePath);
                return false;
            }
            out = new FileOutputStream(localPath + "/" + remoteFile);
            //下载
            boolean downloadFlag = false;
            downloadFlag = ftpClient.retrieveFile(remotePath + "/" + remoteFile, out);
            int replyCode = ftpClient.getReplyCode();
            log.info("下载文件响应码：", replyCode);
            return downloadFlag;
        } catch (Exception e) {
            log.error("FTP下载文件异常！");
            return false;
        } finally {
            try {
                if (out != null) {
                    out.flush();
                    out.close();
                }
                if (null != ftpClient) {
                    ftpClient.disconnect();
                }
            } catch (IOException e) {
                log.error("关闭流发生异常!", e);
            }
        }
    }

    /**
     * 远程上传文件
     */
    @Override
    public boolean putFile(TransferConnectEntity transferConnectEntity, String localFile, String remotePath) {
        getConnection(transferConnectEntity);
        FileInputStream fis = null;
        try {
            if (!ftpClient.changeWorkingDirectory(remotePath)) {
                log.info("没有目录:", remotePath);
                if (!ftpClient.makeDirectory(remotePath)) {
                    log.info("创建文件目录失败：", remotePath);
                    return false;
                }
            }
            //进入文件目录
            ftpClient.changeWorkingDirectory(remotePath);
            //创建文件流
            fis = new FileInputStream(localFile);
            //设置上传目录
            ftpClient.setBufferSize(1024);

            ftpClient.setControlEncoding("UTF-8");
//            ftpClient.enterLocalPassiveMode();
            //设置文件类型（二进制）
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            //FTP服务器上最终的名字
            String uploadFileName = localFile.substring(localFile.lastIndexOf(File.separator) + 1);
            //文件上传
            boolean uploadFlag = ftpClient.storeFile(new String(uploadFileName.getBytes("UTF-8"),"iso-8859-1"), fis);
            return uploadFlag ;
        } catch (Exception e) {
            log.error("FTP上传文件异常！", e);
            return false;
        } finally {
            try {
                if (fis != null) {
                    fis.close();
                }
                if (null != ftpClient) {
                    ftpClient.disconnect();
                }
            } catch (IOException e) {
                log.error("关闭流发生异常!", e);
            }
        }
    }

    @Override
    public boolean putFiles(TransferConnectEntity transferConnectEntity, String localPath, String remotePath) {
        getConnection(transferConnectEntity);
        FileInputStream fis = null;
        try {
            if (!ftpClient.changeWorkingDirectory(remotePath)) {
                log.info("没有目录:", remotePath);
                if (!ftpClient.makeDirectory(remotePath)) {
                    log.info("创建文件目录失败：", remotePath);
                    return false;
                }
            }
            //进入文件目录
            ftpClient.changeWorkingDirectory(remotePath);
            //设置上传目录
            ftpClient.setBufferSize(1024);
            //设置文件类型（二进制）
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);

            File file = new File(localPath);
            File[] files = file.listFiles();
            for (int i = 0; i < files.length; i++) {
                if (files[i].isFile()) {
                    //创建文件流
                    fis = new FileInputStream(files[i]);
                    //FTP服务器上最终的名字
                    String uploadFileName = files[i].getName();
                    //文件上传
                    ftpClient.storeFile(uploadFileName, fis);
                }
            }
            return true ;
        } catch (Exception e) {
            log.error("FTP上传文件异常！", e);
            return false;
        } finally {
            try {
                if (fis != null) {
                    fis.close();
                }
                if (null != ftpClient) {
                    ftpClient.disconnect();
                }
            } catch (IOException e) {
                log.error("关闭流发生异常!", e);
            }
        }
    }
}
